<?php

include_file('src/01_interfaces/Jobs-interfaces.inc.php');

/**
 * AJob - Abstract class implementing all type of Jobs methods
 * 
 * @category Jobs
 * @author polux       
 */
abstract class AJob implements ILoggableItem {
	
	// Static attributes
	/**
	 * Log Object Manager
	 * 
	 * @var LogManager
	 * @static
	 */
	protected static $_o_logObject;
	
	// *********************** Attributes *********************** //	
	/**
	 * Job name
	 * @var string
	 * @access protected
	 */
	protected $_s_jobName;
	/**
	 * Job conf file path
	 * 
	 * @var string
	 * @access protected
	 */
	protected $_s_jobDef_filepath;
	/**
	 * JobManager Object reference
	 *
	 * @var JobsManager
	 * @access protected
	 */
	protected $_o_jobManager;
	/**
	 * Properties to load from files
	 * 
	 * @var array(string)
	 * @access protected
	 */
	protected $_as_propertiesLabel = array(JOB_EXT_ID_PARAMNAME,JOB_EXT_TYPE_PARAMNAME);
	/**
	 * Internal ID of Job
	 * 
	 * @access protected
	 * @var string
	 */
	protected $_s_idJob;
	/**
	 * Properties Values 
	 * 
	 * @var array(string)
	 * @access private
	 */
	private $_as_propertiesValues;
	/**
	 * AJob Tool collection
	 *  
	 * @var array(AJobTool)
	 * @access private
	 */
	private $_ao_jobToolObjects;

	// *********************** Constructors *********************** //
	/**
	 * Default constructor 
	 * @param string 	$p_s_jobName			Job Name
	 * @param string 	$p_s_filepathJobDef		Filepath to job definition file
	 */
	public function __construct($p_s_jobName,$p_s_filepathJobDef) 
	{
		$this->_s_jobName = $p_s_jobName;
		$this->_s_jobDef_filepath = $p_s_filepathJobDef;
		$this->_ao_jobToolObjects = array();
		$this->setProperties();
	}
	
	// *********************** Accessors *********************** //
	/**
	 * Set Internal ID attribute value
	 * 
	 * @access public
	 * @param string $p_s_idValue
	 */
	public function setInternalID($p_s_idValue)
	{
		if(is_string($p_s_idValue))
		{
			$this->_s_idJob = $p_s_idValue;
			JobsManager::getLogManager()->addLogInformation($this, "A Job ID was defined to '".$p_s_idValue."'.");
		}
		else 
			throw new JobGenericException("Error during defining InternalID - Value isn't a string as requiered.");
	}	
	/**
	 * Return Internal ID attribute value
	 * 
	 * @access public
	 * @return string
	 */
	public function getInternalID()
	{
		return $this->_s_idJob;
	}	
	/**
	 * Return Properties value
	 * 
	 * @param string $p_s_ID
	 * @throws Exception
	 * @return string 	null if not found
	 */
	public function getPropertieValue($p_s_ID)
	{
		if(is_null($p_s_ID))
			throw new Exception("getPropertieValue: Invalid null value for ID parameter.");
		
		if(array_key_exists($p_s_ID, $this->_as_propertiesValues))	
		{
			return $this->_as_propertiesValues[$p_s_ID];		
		}
		else 
			return null;
	}
	/**
	 * addAJobTool - Link a Job Tool to this Job
	 * 
	 * @param AJobTool $p_o_jobToolObj
	 */
	public function addAJobTool(AJobTool &$p_o_jobToolObj)
	{
		$l_s_JobToolClassname = get_class($p_o_jobToolObj);
		
		// If a similary tool already exists
		if(array_key_exists($l_s_JobToolClassname, $this->_ao_jobToolObjects))
		{
			JobsManager::getLogManager()->addLogInformation($this, "A similar JobTool of class '".$l_s_JobToolClassname."' was already linked to this Job Object. New linking aborted.");
		}
		else 
		{
			$this->_ao_jobToolObjects[$l_s_JobToolClassname] = &$p_o_jobToolObj;
			JobsManager::getLogManager()->addLogInformation($this, "A JobTool of class '".$l_s_JobToolClassname."' was linked to this Job Object (ID:".$p_o_jobToolObj->getInternalID().")");
		}
	}
	
	// ***********************  Methods  *********************** //
	/**
	 * Loading all properties in memory
	 */
	public function loadPropertiesFromIniFile()
	{
		// Check file exists
		if(file_exists($this->_s_jobDef_filepath))
		{	
			JobsManager::getLogManager()->addLogInformation($this, "Parsing of properties for jobfile called '".$this->_s_jobDef_filepath."' will begin.");
			$l_as_properties = parse_ini_file($this->_s_jobDef_filepath);
			JobsManager::getLogManager()->addLogInformation($this, "Parsing of properties done !");
			
			foreach($this->_as_propertiesLabel as $l_s_tmp => $l_s_key)
			{
				// Item exists
				if(array_key_exists($l_s_key, $l_as_properties))
				{
					$this->_as_propertiesValues[$l_s_key]=$l_as_properties[$l_s_key];
					JobsManager::getLogManager()->addLogInformation($this, "Properties '".$l_s_key."' successfully read (value='".$l_as_properties[$l_s_key]."').");
					if($l_s_key==JOB_EXT_ID_PARAMNAME)
					{
						$this->setInternalID($this->getType()."_".$l_as_properties[$l_s_key]."_".$this->_s_jobName);
					}
				}
				else 
					throw new JobParameterFoundException($l_s_key,$this->_s_jobName);
			}
			JobsManager::getLogManager()->addLogInformation($this, "Properties loading realized successfully !");
		}
		else 
			throw new JobGenericException("Error during loading jobfile properties - File '".$this->_s_jobDef_filepath."' not found.");
	}
	
	
	// *********************** Static Methods *********************** //
	/**
	 * Return the type of a job
	 * 
	 * @param 	string 	$p_s_filepath	File path to Job ini file
	 * @param 	string 	$p_s_jobName	Job name
	 * 
	 * @throws JobParameterFoundException
	 * @throws JobGenericException
	 * 
	 * @return 	string	Type value
	 */
	public static function getTypeFromPropertiesFile($p_s_filepath,$p_s_jobName)
	{
		// Check file exists
		if(file_exists($p_s_filepath))
		{
			$l_as_properties = parse_ini_file($p_s_filepath);
		
			if(array_key_exists(JOB_EXT_TYPE_PARAMNAME, $l_as_properties))
			{
				return $l_as_properties[JOB_EXT_TYPE_PARAMNAME];		
			}
			else
				throw new JobParameterFoundException(JOB_EXT_ID_PARAMNAME,$p_s_jobName);
		}
		else
			throw new JobGenericException("Error during loading jobfile properties - File '".$p_s_filepath."' not found.");
	}
	
	// *********************** Abstract methods *********************** //
	/**
	 * setProperties - Define properties to load
	 * 
	 * @abstract
	 */
	abstract function setProperties();
	/**
	 * getType - Return  Type
	 *
	 * @abstract
	 * @return string
	 */
	abstract function getType();
	
	// *********************** Interfaces methods *********************** //
	
	function addLogEvent($p_s_msg)
	{
		$l_o_log=""; //TODO DEV
	}

	function addAnException(Exception $p_o_ex)
	{
		//TODO DEV
	}
	function getTimestamp()
	{
		
	}
	function setTimestamp()
	{
		
	}
	
	// *********************** END OF CLASS *********************** //
}

?>